home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C ++ / Frameworks / MacZoop 1.6.5 / More Classes / Advanced Dialogs / ZExtraDialogItems.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-14  |  26.4 KB  |  1,162 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            ObjectMacZapp            -- a standard Mac OOP application template
  5. *
  6. *
  7. *
  8. *            ZExtraDialogItems.cpp    -- some other kinds of dialog item objects
  9. *
  10. *
  11. *            © 1997, Graham Cox
  12. *
  13. *
  14. *
  15. *************************************************************************************************/
  16.  
  17. #include    "ZExtraDialogItems.h"
  18. #include    "ZClipboard.h"
  19. #include    "MacZoop.h"
  20. #include    "xDEFJump.h"
  21.  
  22. #include    <Palettes.h>
  23. #include    <LowMem.h>
  24. #include    <Icons.h>
  25.  
  26. // embedded LDEF function:
  27.  
  28. static pascal void    IconListBoxDefProc( short iMessage,
  29.                                         Boolean selected,
  30.                                         Rect* bounds, 
  31.                                         Cell theCell,
  32.                                         short dataOffset,
  33.                                         short dataLength,
  34.                                         ListHandle theList );
  35.  
  36. static void        DrawIconCell(     Rect* r,
  37.                                 IconInfo* info,
  38.                                 Boolean hilited,
  39.                                 Boolean showTitles,
  40.                                 IconHilite hStyle );
  41.  
  42.  
  43. #pragma mark ====== ZLineDialogItem =======
  44.  
  45. /*-------------------------------***  CONSTRUCTOR  ***----------------------------------*/
  46.  
  47. ZLineDialogItem::ZLineDialogItem( ZDialog* aDialog, short item )
  48.     : ZDialogItem( aDialog, item )
  49. {
  50.     itsType = plainLine;
  51.     patIndex = 0;
  52. }
  53.  
  54.  
  55. /*---------------------------------***  DRAWITEM  ***-----------------------------------*/
  56. /*    
  57. draw the line item according to its parameters
  58. ----------------------------------------------------------------------------------------*/
  59.  
  60. void    ZLineDialogItem::DrawItem()
  61. {
  62.     // draw the line using the style set. It is always 1 pixel wide (or 2 if 3D)
  63.     // and the longer dimension of the bounds sets the orientation.
  64.     
  65.     RGBColor    f, b, white = { 0xFFFF, 0xFFFF, 0xFFFF };
  66.     Boolean        isVert = (bounds.bottom - bounds.top) > (bounds.right - bounds.left);
  67.  
  68.     PenSize( 1, 1 );
  69.     
  70.     if ( itsType == patternLine )
  71.     {
  72.         Pattern        p;
  73.         
  74.         GetIndPattern( &p, sysPatListID, patIndex);
  75.         PenPat( &p );
  76.     }
  77.     else
  78.         PenPat( &qd.black );
  79.         
  80.     PenMode( patCopy );
  81.     MoveTo( bounds.left, bounds.top );
  82.     
  83.     // if a 3D line, establish the relevant colours based on the fore and back colours
  84.     // set for the window.
  85.     
  86.     if ( itsType == raised3DLine ||
  87.          itsType == etched3DLine )
  88.     {
  89.         GDHandle    bestDev;
  90.         Rect        r = bounds;
  91.         
  92.         GetForeColor( &f );
  93.         GetBackColor( &b );
  94.         
  95.         LocalToGlobal( &topLeft( r ));
  96.         LocalToGlobal( &botRight( r ));
  97.         
  98.         bestDev = GetMaxDevice( &r );
  99.         
  100.         GetGray( bestDev, &b, &f );
  101.         GetGray( bestDev, &white, &b );
  102.         
  103.         // draw the 3D lines. <f> is the darker colour, <b> is the lighter
  104.         
  105.         if ( isVert )
  106.         {
  107.             if (itsType == raised3DLine )
  108.                 RGBForeColor( &b );
  109.             else
  110.                 RGBForeColor( &f );
  111.                 
  112.             LineTo( bounds.left, bounds.bottom - 1 );
  113.             Move( 1, 0 );
  114.             
  115.             if (itsType == raised3DLine )
  116.                 RGBForeColor( &f );
  117.             else
  118.                 RGBForeColor( &b );
  119.                 
  120.             LineTo( bounds.left + 1, bounds.top );
  121.         }
  122.         else
  123.         {
  124.             if (itsType == raised3DLine )
  125.                 RGBForeColor( &b );
  126.             else
  127.                 RGBForeColor( &f );
  128.                 
  129.             LineTo( bounds.right - 1, bounds.top );
  130.             Move( 0, 1 );
  131.             
  132.             if (itsType == raised3DLine )
  133.                 RGBForeColor( &f );
  134.             else
  135.                 RGBForeColor( &b );
  136.                 
  137.             LineTo( bounds.left, bounds.top + 1 );
  138.         }
  139.     }
  140.     else
  141.     {
  142.         // a plain or patterned line
  143.     
  144.         if ( isVert )
  145.             LineTo( bounds.left, bounds.bottom - 1 );
  146.         else
  147.             LineTo( bounds.right - 1, bounds.top );
  148.     }
  149.     
  150.     PenNormal();
  151.     ForeColor( blackColor );
  152. }
  153.  
  154.  
  155. /*---------------------------------***  INITITEM  ***-----------------------------------*/
  156. /*    
  157. set up line parameters from original magic string params
  158. ----------------------------------------------------------------------------------------*/
  159.  
  160. void    ZLineDialogItem::InitItem( const long param1, const long param2 )
  161. {
  162.     itsType = ( LineType ) param1;
  163.     patIndex = param2;
  164. }
  165.  
  166.  
  167. #pragma mark -
  168. #pragma mark ======= ZIconListBox ========
  169.  
  170.  
  171. /*-------------------------------***  CONSTRUCTOR  ***---------------------------------*/
  172.  
  173. ZIconListBox::ZIconListBox( ZDialog* aDialog, short item )
  174.     : ZListDialogItem( aDialog, item )
  175. {
  176.     showTitles = TRUE;
  177.     smallIcons = FALSE;
  178.     iHilite = iconDefaultHilite;
  179. }
  180.  
  181. /*--------------------------------***  DESTRUCTOR  ***---------------------------------*/
  182.  
  183. ZIconListBox::~ZIconListBox()
  184. {
  185.     if ( theList )
  186.     {
  187.         // dispose icons
  188.         
  189.         DisposeIconCells();
  190.         
  191.         // get rid of the embedded LDEF handle if it's there
  192.         
  193.         Handle    h = (*theList)->listDefProc;
  194.         
  195.         if ( h )
  196.         {
  197.             Cell    c = { 0, 0 };
  198.             
  199.             IconListBoxDefProc( lCloseMsg, FALSE, &bounds, c, 0, 0, theList );
  200.             DisposeHandle( h );
  201.         }
  202.         // important:
  203.             
  204.         (*theList)->listDefProc = NULL;
  205.     }
  206. }
  207.  
  208. /*---------------------------------***  INITITEM  ***-----------------------------------*/
  209. /*    
  210. set up icon listbox parameters from original magic string params
  211. ----------------------------------------------------------------------------------------*/
  212.  
  213. void        ZIconListBox::InitItem( const long param1, const long param2 )
  214. {
  215.     // make the list
  216.     
  217.     MakeMacList( param1 );
  218.     
  219.     // install the icons from the template
  220.     
  221.     if ( param1 > 0 )
  222.         AddIconCells( param1 );
  223.     
  224.     // do the usual trick of sizing the bounds to encompass a whole number
  225.     // of cells
  226.     
  227.     short    cellHeight = (*theList)->cellSize.v;
  228.     short    cellWidth  = (*theList)->cellSize.h;
  229.     short    adjustAmount;
  230.     Boolean    hasH, hasV;
  231.     
  232.     hasH = ((*theList)->hScroll != NULL);
  233.     hasV = ((*theList)->vScroll != NULL);
  234.     
  235.     adjustAmount = (bounds.bottom - bounds.top - (hasH? 17 : 2)) % cellHeight;
  236.     bounds.bottom -= adjustAmount;
  237.     
  238.     adjustAmount = (bounds.right - bounds.left - (hasV? 17 : 2)) % cellWidth;
  239.     bounds.right -= adjustAmount;
  240.     
  241.     LSize( bounds.right - bounds.left - (hasV? 17 : 2),
  242.            bounds.bottom - bounds.top - (hasH? 17 : 2),
  243.            theList );
  244.     
  245.     // ready to go, so activate the list appropriately
  246.     
  247.     LActivate( TRUE, theList );
  248.     ActivateListItem( FALSE );
  249. }
  250.  
  251. /*-------------------------------***  MAKEMACLIST  ***----------------------------------*/
  252. /*    
  253. build the icon list structures. This is a normal List Manager list but using a custom
  254. LDEF that we have embedded within this source file. Each cell of the list contains an
  255. icon and optionally a title string below it. Layout can be horizontal or vertical.
  256. ----------------------------------------------------------------------------------------*/
  257.  
  258. void        ZIconListBox::MakeMacList( const short listTemplateID )
  259. {
  260.     Point                cellSize = { 34, 0 };
  261.     ListTemplateHdl        ltH;
  262.     IconListBoxHdl        lbH;
  263.     Rect                r, dataBounds = { 0, 0, 0, 1 };
  264.     Boolean                hasV = TRUE, hasH = FALSE;
  265.     ZDialog*            zd = (ZDialog*) GetBoss();
  266.     
  267.     // get the bounding box for this item
  268.     
  269.     r = bounds;
  270.     InsetRect( &r, 1, 1 );
  271.     
  272.     // see if there's a LIST template, which will define our font, etc
  273.     
  274.     if ( listTemplateID != 0 )
  275.     {
  276.         ltH = ( ListTemplateHdl ) GetResource( kListTemplateResType, listTemplateID );
  277.     
  278.         if ( ltH )
  279.         {
  280.             // there is a template, so use that to define the list.
  281.         
  282.             dataBounds.right     = (*ltH)->columns;
  283.             dataBounds.bottom     = (*ltH)->rows;
  284.             hasV                 = (*ltH)->hasVertScroll;
  285.             hasH                 = (*ltH)->hasHorizScroll;
  286.             canBeHandler         = (*ltH)->keyboardNav;
  287.             fontSize             = (*ltH)->fontSize;
  288.             strListID            = (*ltH)->stringsListID;
  289.             
  290.             GetFNum((*ltH)->fontName, &font );
  291.             
  292.             ReleaseResource((Handle) ltH );
  293.         }
  294.         
  295.         // get some basic settings from the ICLB resource
  296.         
  297.         lbH = (IconListBoxHdl) GetResource( kIconListTemplateResType, listTemplateID );
  298.         
  299.         if ( lbH )
  300.         {
  301.             showTitles = (*lbH)->addTitles;
  302.             iHilite = (IconHilite)(*lbH)->hiliteStyle;
  303.         
  304.             ReleaseResource((Handle) lbH );
  305.         }
  306.     }        
  307.     // allow space for the scrollbars we want
  308.     
  309.     if ( hasV )
  310.         r.right -= 15;
  311.         
  312.     if ( hasH )
  313.         r.bottom -= 15;
  314.         
  315.     // compute the cell height based on the size of an icon plus the current font
  316.     
  317.     if ( showTitles )
  318.     {
  319.         FontInfo    fi;
  320.         
  321.         GetFontInfo( &fi );
  322.         cellSize.v = 34 + fi.ascent + fi.descent + fi.leading;
  323.     }
  324.     
  325.     if ( hasH )
  326.         cellSize.h = 64;
  327.         
  328.     // make the list initally
  329.     
  330.     short    saveFont, saveSize;
  331.     
  332.     SetUpFontForList( &saveFont, &saveSize );
  333.     
  334.     theList = LNew( &r, &dataBounds, cellSize, 0, zd->GetMacWindow(), TRUE, FALSE, hasH, hasV );
  335.     FailNIL( theList );
  336.     
  337.     // now scrungle our cunning LDEF into it
  338.     
  339.     InstallIconLDEF();
  340.     
  341.     // now we just need to install all our icons, but we leave that to InitItem, which called
  342.     // this method in the first place
  343.     
  344.     if (font != 0 &&
  345.         fontSize != 0 )
  346.     {
  347.         TextFont( saveFont );
  348.         TextSize( saveSize );
  349.     }
  350.     
  351.     // by default, icon lists only allow one selection at a time (probably most common use)
  352.     // change this line or override for other behaviours.
  353.     
  354.     (*theList)->selFlags = lOnlyOne;
  355. }
  356.  
  357.  
  358. /*-----------------------------***  INSTALLICONLDEF  ***--------------------------------*/
  359. /*    
  360. set the list to use our embedded LDEF and make sure it's inited properly
  361. ----------------------------------------------------------------------------------------*/
  362.  
  363. void        ZIconListBox::InstallIconLDEF()
  364. {
  365.     Handle    ldefHand;
  366.     Rect    r = {0, 0, 0, 0};
  367.     Cell    aCell = { 0, 0 };
  368.     
  369.     FailNIL( ldefHand = GetUniversalFunctionHandle((ProcPtr) IconListBoxDefProc, uppListDefProcInfo ));
  370.     
  371.     (*theList)->listDefProc = ldefHand;
  372.     
  373.     // set the list's refcon to this so that the LDEF can callback into us if need be
  374.     
  375.     (*theList)->refCon = (long) this;
  376.     
  377.     // the "init" message won't have been sent, since it was inited using the system LDEF,
  378.     // so simply call it directly in case the LDEF does something here. 
  379.     
  380.     IconListBoxDefProc( lInitMsg, FALSE, &r, aCell, 0, 0, theList );
  381. }
  382.  
  383.  
  384. /*-------------------------------***  ADDICONCELLS  ***---------------------------------*/
  385. /*    
  386. read the icon listbox template and fetch all the icons, etc needed and set them up
  387. ----------------------------------------------------------------------------------------*/
  388.  
  389. void        ZIconListBox::AddIconCells( const short templateID )
  390. {
  391.     short            i;
  392.     Cell            c = { 0, 0 };
  393.     IconInfo        info;
  394.     Boolean            isHList;
  395.     IconListBoxHdl    lbH;
  396.     
  397.     isHList = ((*theList)->hScroll != NULL) && ((*theList)->vScroll == NULL);
  398.     
  399.     // attempt to locate the template (ICLB) with the ID passed
  400.     
  401.     lbH = (IconListBoxHdl) GetResource( kIconListTemplateResType, templateID );
  402.     
  403.     if ( lbH )
  404.     {
  405.         // obtained the template, now construct the icon list
  406.         
  407.         for( i = 0; i < (*lbH)->numIcons; i++ )
  408.         {
  409.             // locate each icon and load it as needed
  410.             
  411.             info.iconID = (*lbH)->icons[i].resID;
  412.  
  413.             switch ((*lbH)->icons[i].iconType)
  414.             {
  415.                 case 0:        // plain black & white icon
  416.                     info.iType = IconPlain;
  417.                     info.theIcon = GetIcon( info.iconID );
  418.                     break;
  419.                 case 1:        // 'cicn' resource
  420.                     info.iType = IconColour;
  421.                     info.theIcon = (Handle) GetCIcon( info.iconID );
  422.                     break;
  423.                 case 2:        // indexed icon, etc
  424.                 default:
  425.                     info.iType = IconIndexed;
  426.                     info.theIcon = NULL;
  427.                     break;
  428.             }
  429.             
  430.             // get the title string from the relevant string list
  431.             
  432.             GetIndString( info.title, (*lbH)->titleListResID, (*lbH)->icons[i].nameIndex );
  433.             
  434.             // to make the titles look nicer when hilited, we add a space in front and another
  435.             // at the end of the title
  436.             
  437.             BlockMoveData( &info.title[1], &info.title[2], info.title[0] );
  438.             info.title[1] = ' ';
  439.             info.title[0] += 2;
  440.             info.title[ info.title[0]] = ' ';
  441.             info.userData = 0;
  442.         
  443.             // add the resulting nugget of info to the list
  444.             
  445.             if (isHList)
  446.                 c.h = LAddColumn( 1, c.h + 1, theList );
  447.             else
  448.                 c.v = LAddRow( 1, c.v + 1, theList );
  449.             
  450.             LSetCell( &info, sizeof( IconInfo ), c, theList );
  451.         }
  452.         ReleaseResource((Handle) lbH );
  453.     }
  454. }
  455.  
  456. /*-----------------------------***  DISPOSEICONCELLS  ***-------------------------------*/
  457. /*    
  458. disposes the icons when the list is closed
  459. ----------------------------------------------------------------------------------------*/
  460.  
  461. void    ZIconListBox::DisposeIconCells()
  462. {
  463.     Cell        c = {0, 0};
  464.     short        row, col, len;
  465.     IconInfo    info;
  466.     
  467.     for( col = 0; col < (*theList)->dataBounds.right; col++ )
  468.     {
  469.         for( row = 0; row < (*theList)->dataBounds.bottom; row++ )
  470.         {
  471.             c.h = col;
  472.             c.v = row;
  473.             len = sizeof( IconInfo );
  474.             
  475.             LGetCell( &info, &len, c, theList );
  476.             
  477.             // determine the type of icon and release it
  478.             
  479.             if ( info.theIcon )
  480.             {
  481.                 switch( info.iType )
  482.                 {
  483.                     case IconPlain:
  484.                         ReleaseResource( info.theIcon );
  485.                         break;
  486.                     case IconColour:
  487.                         DisposeCIcon((CIconHandle) info.theIcon );    
  488.                         break;
  489.                     case IconSuite:
  490.                         DisposeIconSuite( info.theIcon, TRUE );
  491.                         break;
  492.                 }
  493.             }
  494.         }
  495.     }
  496. }
  497.  
  498. #pragma mark -
  499. #pragma mark ======= Embedded LDEF ======
  500.  
  501.  
  502. /*----------------------------***  IconListBoxDefProc  ***------------------------------*/
  503.  
  504. static pascal void    IconListBoxDefProc( short iMessage,
  505.                                         Boolean selected,
  506.                                         Rect* bounds,
  507.                                         Cell theCell, 
  508.                                         short dataOffset,
  509.                                         short dataLength,
  510.                                         ListHandle theList )
  511. {
  512.     ZIconListBox*    zb = (ZIconListBox*)(*theList)->refCon;
  513.     IconInfo        info;
  514.     
  515.     switch( iMessage )
  516.     {
  517.         case lInitMsg:
  518.             break;
  519.         case lDrawMsg:
  520.         case lHiliteMsg:
  521.             // set up a pointer to the list's cell data
  522.             
  523.             LGetCell( &info, &dataLength, theCell, theList );
  524.             DrawIconCell(    bounds,
  525.                             &info,
  526.                             selected,
  527.                             zb->ShowTitles(),
  528.                             zb->GetHiliteStyle());
  529.             
  530.             break;
  531.         case lCloseMsg:
  532.             break;
  533.     }
  534. }
  535.  
  536.  
  537.  
  538. static void        DrawIconCell( Rect* r, IconInfo* info, Boolean hilited, Boolean showTitles, IconHilite hStyle )
  539. {
  540.     // draw the icon in the rectangle, applying information from info, etc
  541.     
  542.     Rect    ir = { 0, 0, 32, 32 };
  543.     short    iconTransform;
  544.     
  545.     // centre the icon's rect horizontally in the cell
  546.     
  547.     OffsetRect( &ir, ((r->left + r->right) / 2) - (( ir.right - ir.left ) / 2), r->top + 1 );
  548.     
  549.     // set up the icon transform based on the selection options set
  550.     
  551.     if (hilited && (hStyle & iconHiliteDarken))
  552.         iconTransform = ttSelected;
  553.     else
  554.         iconTransform = ttNone;
  555.     
  556.     // plot the icon according to its type
  557.     
  558.     switch ( info->iType )
  559.     {
  560.         case IconIndexed:
  561.             PlotIconID( &ir, atNone, iconTransform, info->iconID );
  562.             break;
  563.         case IconPlain:
  564.             if (info->theIcon)
  565.             {
  566.                 LoadResource( info->theIcon );
  567.                 PlotIcon( &ir, info->theIcon );
  568.                 
  569.                 if (hilited)
  570.                     InvertRect( &ir );    
  571.             }
  572.             break;
  573.         case IconColour:
  574.             if (info->theIcon)
  575.             {
  576.                 // for these icons, the rect may not be 32 x 32, so we need to get the real
  577.                 // size and centre it accordingly.
  578.                 
  579.                 CIconHandle    ci = (CIconHandle) info->theIcon; 
  580.                 
  581.                 ir = (*ci)->iconPMap.bounds;
  582.                 OffsetRect( &ir, -ir.left, -ir.top );
  583.                 OffsetRect( &ir, ((r->left + r->right) / 2) - (( ir.right - ir.left ) / 2),
  584.                             r->top + 33 - ir.bottom - ir.top );
  585.                 
  586.                 PlotCIconHandle( &ir, atNone, iconTransform, ci );
  587.             }
  588.             break;
  589.     }    
  590.     
  591.     // if we want bold border as well, draw it. Actually, this is pretty dismal looking
  592.     // and I can't imagine why anyone would want it! You have been warned!
  593.     
  594.     if ( hStyle & iconHiliteBoldBorder )
  595.     {
  596.         InsetRect( &ir, -4, -4 );
  597.         PenSize( 3, 3 );
  598.         
  599.         if (hilited)
  600.             PenMode( patOr );
  601.         else
  602.             PenMode( patBic );
  603.         
  604.         FrameRect( &ir );    
  605.     }
  606.     
  607.     // draw the icon title if required
  608.     
  609.     if ( showTitles )
  610.     {
  611.         FontInfo    fi;
  612.         GetFontInfo( &fi );
  613.         
  614.         short    tLen = StringWidth( info->title );
  615.         
  616.         MoveTo(((r->left + r->right) / 2) - (tLen / 2),  r->top + 33 + fi.ascent );
  617.         
  618.         if (hilited && ( hStyle & iconHiliteInvertTitle))
  619.             TextMode( notSrcCopy );
  620.         else
  621.             TextMode( srcCopy );
  622.         
  623.         DrawString( info->title );
  624.         TextMode( srcOr );
  625.     }
  626. }
  627.  
  628. #pragma mark -
  629. #pragma mark ===== ZScrollingTextBox =====
  630.  
  631.  
  632. static pascal void    ScrollProc( ControlHandle ch, short partCode );
  633.  
  634. static ControlActionUPP    gSBarActionUPP = NewControlActionProc( ScrollProc );
  635.  
  636. /*-------------------------------***  CONSTRUCTOR  ***----------------------------------*/
  637.  
  638.  
  639. ZScrollingTextBox::ZScrollingTextBox( ZDialog* aDialog, short item )
  640.     : ZDialogItem( aDialog, item )
  641. {
  642.     te = NULL;
  643.     scroll = NULL;
  644.     editable = FALSE;
  645.     resID = 0;
  646. }
  647.  
  648. /*-------------------------------***  DESTRUCTOR  ***-----------------------------------*/
  649.  
  650.  
  651. ZScrollingTextBox::~ZScrollingTextBox()
  652. {
  653.     if ( te )
  654.         TEDispose( te );
  655.         
  656.     if ( scroll )
  657.         DisposeControl( scroll );
  658. }
  659.  
  660. /*---------------------------------***  INITITEM  ***-----------------------------------*/
  661. /*    
  662. set up the textbox item
  663. ----------------------------------------------------------------------------------------*/
  664.  
  665. void        ZScrollingTextBox::InitItem( const long param1, const long param2 )
  666. {
  667.     resID = LoWord( param1 );
  668.     editable = ( param2 != 0 );
  669.     
  670.     // get the lineheight and page height of the text
  671.     
  672.     FontInfo    fi;
  673.     
  674.     GetFontInfo( &fi );
  675.     lineHeight = fi.ascent + fi.descent + fi.leading;
  676.     pageHeight = bounds.bottom - bounds.top - lineHeight;
  677.     
  678.     // construct the mac stuff
  679.     
  680.     MakeMacTEAndScroll();
  681.     
  682.     // load the initial text
  683.     
  684.     PreloadText();
  685.     
  686.     // if the text is ediable, we can be the handler too
  687.     
  688.     canBeHandler = editable;
  689. }
  690.  
  691. /*---------------------------------***  DRAWITEM  ***-----------------------------------*/
  692. /*    
  693. refresh the item
  694. ----------------------------------------------------------------------------------------*/
  695.  
  696. void        ZScrollingTextBox::DrawItem()
  697. {
  698.     TEUpdate( &bounds, te );
  699.     FrameRect( &bounds );
  700.     
  701.     #ifdef _GREYSCALE_APPEARANCE
  702.     
  703.     FrameGrayRect( &bounds );
  704.     
  705.     #endif
  706. }
  707.  
  708. /*---------------------------------***  CLICKITEM  ***----------------------------------*/
  709. /*    
  710. handle mouse click in item
  711. ----------------------------------------------------------------------------------------*/
  712.  
  713. void        ZScrollingTextBox::ClickItem( const Point where, const short modifiers )
  714. {
  715.     if ( enabled )
  716.     {
  717.         // make sure this is the handler when clicked
  718.         
  719.         if (! isHandler && canBeHandler)
  720.             BecomeHandler( TRUE );
  721.         
  722.         // detect and handle click in scrollbar
  723.         
  724.         if ( PtInScrollbar( where ))
  725.         {
  726.             short            partCode;
  727.             ControlHandle    ch;
  728.             ZDialog*        zd = (ZDialog*) GetBoss();
  729.             
  730.             partCode = FindControl( where, zd->GetMacWindow(), &ch );
  731.             
  732.             if ( partCode > 0 )
  733.             {
  734.                 if ( partCode == kControlIndicatorPart )
  735.                 {
  736.                     short    delta = GetControlValue( scroll );
  737.                     
  738.                     partCode = TrackControl( scroll, where, NULL );
  739.                     
  740.                     if ( partCode == kControlIndicatorPart )
  741.                     {
  742.                         delta -= GetControlValue( scroll );
  743.                     
  744.                         Scroll( delta );
  745.                     }
  746.                 }
  747.                 else
  748.                     partCode = TrackControl( scroll, where, gSBarActionUPP );
  749.             }
  750.         }
  751.         else
  752.         {
  753.             if ( editable )
  754.             {
  755.                 TEClick( where, modifiers & shiftKey, te );
  756.                 CalScroll();
  757.             }
  758.         }
  759.     }
  760. }
  761.  
  762. /*-------------------------------***  ADJUSTCURSOR  ***---------------------------------*/
  763. /*    
  764. set cursor to i-beam over editable text
  765. ----------------------------------------------------------------------------------------*/
  766.  
  767. void        ZScrollingTextBox::AdjustCursor( const Point where, const short modifiers )
  768. {
  769.     if ( PtInScrollbar( where ))
  770.         InitCursor();
  771.     else
  772.     {
  773.         if ( editable )
  774.         {
  775.             CursHandle    ch = GetCursor( iBeamCursor );
  776.             
  777.             SetCursor( *ch );
  778.         }
  779.     }
  780. }
  781.  
  782. /*---------------------------------***  ACTIVATE  ***-----------------------------------*/
  783. /*    
  784. activate/deactivate the text
  785. ----------------------------------------------------------------------------------------*/
  786.  
  787. void        ZScrollingTextBox::Activate( const Boolean isActive )
  788. {
  789.     ZAdvancedDialog* zd = (ZAdvancedDialog*) GetBoss();
  790.     
  791.     if ( isHandler && zd->HasMultipleFoci())
  792.         DrawBorder( isActive );
  793.  
  794.     if ( editable )
  795.     {
  796.         if ( isActive )
  797.             TEActivate( te );
  798.         else
  799.             TEDeactivate( te );
  800.     }
  801. }
  802.  
  803. /*-----------------------------***  BECOMEHANDLER  ***----------------------------------*/
  804. /*    
  805. become the current keyboard handler
  806. ----------------------------------------------------------------------------------------*/
  807.  
  808. void        ZScrollingTextBox::BecomeHandler( Boolean isBecoming )
  809. {
  810.     inherited::BecomeHandler( isBecoming );
  811.     
  812.     if ( editable )
  813.         Activate( isHandler );
  814. }
  815.  
  816.  
  817. /*----------------------------------***  DOCUT  ***-------------------------------------*/
  818. /*    
  819. handle the Cut command
  820. ----------------------------------------------------------------------------------------*/
  821.  
  822. void        ZScrollingTextBox::DoCut()
  823. {
  824.     if ( editable )
  825.     {
  826.         TECut( te );
  827.         CalScroll();
  828.     }
  829. }
  830.  
  831. /*----------------------------------***  DOCOPY  ***------------------------------------*/
  832. /*    
  833. handle the Copy command
  834. ----------------------------------------------------------------------------------------*/
  835.  
  836. void        ZScrollingTextBox::DoCopy()
  837. {
  838.     if ( editable )
  839.         TECopy( te );
  840. }
  841.  
  842. /*---------------------------------***  DOPASTE  ***------------------------------------*/
  843. /*    
  844. handle the Paste command
  845. ----------------------------------------------------------------------------------------*/
  846.  
  847. void        ZScrollingTextBox::DoPaste()
  848. {
  849.     if ( editable )
  850.     {
  851.         TEPaste( te );
  852.         CalScroll();
  853.     }
  854. }
  855.  
  856. /*---------------------------------***  DOCLEAR  ***------------------------------------*/
  857. /*    
  858. handle the Clear command
  859. ----------------------------------------------------------------------------------------*/
  860.  
  861. void        ZScrollingTextBox::DoClear()
  862. {
  863.     if ( editable )
  864.     {
  865.         TEDelete( te );
  866.         CalScroll();
  867.     }
  868. }
  869.  
  870.  
  871. /*-------------------------------***  DOSELECTALL  ***----------------------------------*/
  872. /*    
  873. handle the Select All command
  874. ----------------------------------------------------------------------------------------*/
  875.  
  876. void        ZScrollingTextBox::DoSelectAll()
  877. {
  878.     if ( editable )
  879.         TESetSelect( 0, 32767, te );
  880. }
  881.  
  882.  
  883. /*-------------------------------***  CANPASTETYPE  ***---------------------------------*/
  884. /*    
  885. see if there is pasteable data on the clipboard- we can handle TEXT.
  886. ----------------------------------------------------------------------------------------*/
  887.  
  888. Boolean        ZScrollingTextBox::CanPasteType()
  889. {
  890.     return gClipboard->QueryType( 'TEXT' );
  891. }
  892.  
  893.  
  894. /*-------------------------------***  UPDATEMENUS  ***----------------------------------*/
  895. /*    
  896. update edit menu commands for this item where appropriate
  897. ----------------------------------------------------------------------------------------*/
  898.  
  899. void        ZScrollingTextBox::UpdateMenus()
  900. {
  901.     inherited::UpdateMenus();
  902.     
  903.     MenuHandle    mH;
  904.     
  905.     if ( editable )
  906.         gMenuBar->EnableCommand( kCmdSelectAll );
  907. }
  908.  
  909.  
  910. /*-----------------------------------***  TYPE  ***-------------------------------------*/
  911. /*    
  912. type text if editable
  913. ----------------------------------------------------------------------------------------*/
  914.  
  915. void        ZScrollingTextBox::Type( const char theKey )
  916. {
  917.     inherited::Type( theKey );
  918.     
  919.     if ( editable && ( theKey != 0x09 ))
  920.     {
  921.         TEKey( theKey, te );
  922.         CalScroll();
  923.     }
  924. }
  925.  
  926. /*-----------------------------------***  IDLE  ***-------------------------------------*/
  927. /*    
  928. blink cursor in editable text
  929. ----------------------------------------------------------------------------------------*/
  930.  
  931. void        ZScrollingTextBox::Idle()
  932. {
  933.     if ( editable )
  934.         TEIdle( te );
  935.         
  936.     inherited::Idle();
  937. }
  938.  
  939. /*----------------------------------***  SETTEXT  ***-----------------------------------*/
  940. /*    
  941. set the item's text
  942. ----------------------------------------------------------------------------------------*/
  943.  
  944. void        ZScrollingTextBox::SetText( Handle textH, Handle styleH )
  945. {
  946.     FailOSErr(( textH == NULL )? paramErr : noErr );
  947.     
  948.     long    tLen = GetHandleSize( textH );
  949.     
  950.     TEActivate( te );
  951.     TESetSelect( 0, 32767, te );
  952.     TEDelete( te );
  953.     
  954.     HLock( textH );
  955.     TEStyleInsert( *textH, tLen, (StScrpHandle) styleH, te );
  956.     HUnlock( textH );
  957.     
  958.     TESetSelect( 0, 0, te );
  959.     TEDeactivate( te );
  960.         
  961.     CalScroll();
  962. }
  963.  
  964. /*----------------------------------***  GETTEXT  ***-----------------------------------*/
  965. /*    
  966. get the text. This copies the text (and optionally the style) into the handles passed,
  967. resizing them as needed and replacing any existing data therein.
  968. ----------------------------------------------------------------------------------------*/
  969.  
  970. void        ZScrollingTextBox::GetText( Handle textH, Handle styleH )
  971. {
  972.     FailOSErr(( textH == NULL )? paramErr : noErr );
  973.     
  974.     char            hs = HGetState((*te)->hText);
  975.     StScrpHandle    st = NULL;
  976.     short            se, ss;
  977.     
  978.     HLock((*te)->hText);
  979.     
  980.     try
  981.     {
  982.         FailOSErr( PtrToXHand( *(*te)->hText, textH, (*te)->teLength ));
  983.         
  984.         // if the styleH is not NULL, get the style handle too
  985.         
  986.         if ( styleH )
  987.         {
  988.             se = (*te)->selEnd;
  989.             ss = (*te)->selStart;
  990.             
  991.             TESetSelect( 0, 32767, te );
  992.             
  993.             st = TEGetStyleScrapHandle( te );
  994.         
  995.             if ( st )
  996.             {
  997.                 HLock((Handle) st );
  998.             
  999.                 FailOSErr( PtrToXHand( *st, styleH, GetHandleSize((Handle) st )));
  1000.             
  1001.                 HUnlock((Handle) st );
  1002.                 DisposeHandle((Handle) st );
  1003.             }
  1004.             
  1005.             TESetSelect( ss, se, te );
  1006.         }    
  1007.     }
  1008.     catch( OSErr err )
  1009.     {
  1010.         HSetState((*te)->hText, hs );
  1011.         
  1012.         if ( st )
  1013.         {
  1014.             DisposeHandle((Handle) st );
  1015.             TESetSelect( ss, se, te );
  1016.         }
  1017.         
  1018.         throw err;
  1019.     }
  1020.     
  1021.     HSetState((*te)->hText, hs );
  1022. }
  1023.  
  1024.  
  1025. /*---------------------------***  MAKEMACTEANDSCROLL  ***-------------------------------*/
  1026. /*    
  1027. create the textedit record and scrollbar
  1028. ----------------------------------------------------------------------------------------*/
  1029.  
  1030. void        ZScrollingTextBox::MakeMacTEAndScroll()
  1031. {
  1032.     Rect        rView;
  1033.     ZDialog*    zd;
  1034.     WindowPtr    w;
  1035.     
  1036.     zd = (ZDialog*) GetBoss();
  1037.     w = zd->GetMacWindow();
  1038.     
  1039.     rView = bounds;
  1040.     rView.right -= 15;            // allow for scrollbar's width
  1041.     InsetRect( &rView, 3, 3 );
  1042.     
  1043.     FailNIL( te = TEStyleNew( &rView, &rView ));
  1044.     
  1045.     // make the scrollbar
  1046.     
  1047.     rView = bounds;
  1048.     rView.left = rView.right - 16;
  1049.     
  1050.     FailNIL( scroll = NewControl( w, &rView, NULL, TRUE, 0, 0, 0, scrollBarProc, (long) this ));
  1051.  
  1052.     TEAutoView( TRUE, te );
  1053. }
  1054.  
  1055. /*-------------------------------***  PRELOADTEXT  ***----------------------------------*/
  1056. /*    
  1057. install text from resource
  1058. ----------------------------------------------------------------------------------------*/
  1059.  
  1060. void        ZScrollingTextBox::PreloadText()
  1061. {
  1062.     Handle t, s;
  1063.     
  1064.     if ( resID > 0 )
  1065.     {
  1066.         t = GetResource( 'TEXT', resID );
  1067.         
  1068.         if ( t )
  1069.         {
  1070.             s = GetResource( 'styl', resID );
  1071.     
  1072.             SetText( t, s );
  1073.         
  1074.             if ( s )
  1075.                 ReleaseResource ( s );
  1076.                 
  1077.             ReleaseResource( t );
  1078.         }
  1079.     }
  1080. }
  1081.  
  1082.  
  1083. /*--------------------------------***  CALSCROLL  ***-----------------------------------*/
  1084. /*    
  1085. adjust scrollbar max according to amount of text and height of box, etc.
  1086. ----------------------------------------------------------------------------------------*/
  1087.  
  1088. void        ZScrollingTextBox::CalScroll()
  1089. {
  1090.     short     tHeight = TEGetHeight( 32767, 0, te );
  1091.     short    sMax;
  1092.     
  1093.     // scrollbar max is set to the height of the lines less the height of bounds
  1094.     
  1095.     sMax = tHeight - ( bounds.bottom - bounds.top - 6 );
  1096.     
  1097.     if ( sMax < 0 )
  1098.         sMax = 0;
  1099.     
  1100.     SetControlMaximum( scroll, sMax ); 
  1101.     
  1102.     // compute value
  1103.     
  1104.     sMax = (*te)->viewRect.top - (*te)->destRect.top;
  1105.     
  1106.     SetControlValue( scroll, sMax );    
  1107. }
  1108.  
  1109.  
  1110. Boolean        ZScrollingTextBox::PtInScrollbar( const Point mouse )
  1111. {
  1112.     Rect    r = bounds;
  1113.     
  1114.     r.left = r.right - 15;
  1115.     
  1116.     return PtInRect( mouse, &r );
  1117. }
  1118.  
  1119.  
  1120.  
  1121. void        ZScrollingTextBox::Scroll( short delta )
  1122. {
  1123.     TEScroll( 0, delta, te );
  1124. }
  1125.  
  1126.  
  1127. void        ZScrollingTextBox::DoScroll( short partCode )
  1128. {
  1129.     short sDelta = 0;
  1130.     
  1131.     switch ( partCode )
  1132.     {
  1133.         case kControlUpButtonPart:
  1134.             sDelta = -lineHeight;
  1135.             break;
  1136.         case kControlDownButtonPart:
  1137.             sDelta = lineHeight;
  1138.             break;
  1139.         case kControlPageUpPart:
  1140.             sDelta = -pageHeight;
  1141.             break;
  1142.         case kControlPageDownPart:
  1143.             sDelta = pageHeight;
  1144.             break;
  1145.     }
  1146.     
  1147.     short    sv = GetControlValue( scroll );
  1148.     
  1149.     SetControlValue( scroll, sv + sDelta );
  1150.     sDelta = sv - GetControlValue( scroll );
  1151.     
  1152.     Scroll( sDelta );
  1153. }
  1154.  
  1155.  
  1156. static pascal void    ScrollProc( ControlHandle ch, short partCode )
  1157. {
  1158.     ZScrollingTextBox*    zi = (ZScrollingTextBox*) GetControlReference( ch );
  1159.  
  1160.     if ( zi )
  1161.         zi->DoScroll( partCode );
  1162. }